home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1998 July
/
EnigmA AMIGA RUN 29 (1998)(G.R. Edizioni)(IT)[!][issue 1998-07 & 08].iso
/
recent
/
gms_pi.lha
/
Pictures
/
PIC_Init.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-06-22
|
13KB
|
448 lines
#include <proto/dpkernel.h>
#include <system/all.h>
#include <dpkernel/prefs.h>
#include "defs.h"
/************************************************************************************
** Action: CheckFile()
** Object: Picture
*/
LIBFUNC LONG PIC_CheckFile(mreg(__a0) struct File *File,
mreg(__a1) LONG *Buffer)
{
if (Buffer[0] IS CODE_FORM AND Buffer[2] IS CODE_ILBM) {
DPrintF("CheckFile:","File identified as Picture");
return(99);
}
else {
return(NULL);
}
}
/************************************************************************************
** Action: Free()
** Object: Picture
*/
LIBFUNC void PIC_Free(mreg(__a0) struct Picture *pic)
{
FreeMemBlock(pic->prvData);
FreeMemBlock(pic->prvPalette);
Free(pic->Bitmap);
FreeMemBlock(pic);
PictureMod->Public->OpenCount--;
}
/************************************************************************************
** Action: Get()
** Object: Picture
*/
LIBFUNC struct Picture * PIC_Get(mreg(__a0) struct Stats *Stats)
{
struct Picture *Picture;
if (Picture = AllocMemBlock(sizeof(struct Picture), Stats->MemFlags|MEM_DATA|MEM_UNTRACKED)) {
Picture->Head.ID = ID_PICTURE;
Picture->Head.Version = VER_PICTURE;
if (Picture->Bitmap = Get(ID_BITMAP|GET_NOTRACK)) {
Picture->Bitmap->Parent = Picture;
PictureMod->Public->OpenCount++;
return(Picture);
}
else DPrintF("!Get:","Failed to obtain a Bitmap for this Picture.");
FreeMemBlock(Picture);
}
else ErrCode(ERR_MEMORY);
return(NULL);
}
/************************************************************************************
** Action: Init()
** Object: Picture
**
** Loads in a picture, automatically depacking it, assessing the info header and
** then copying it out to the bitmap.
*/
LIBFUNC LONG PIC_Init(mreg(__a0) struct Picture *Picture)
{
struct File *File = NULL;
struct BMHD *BMHD = NULL;
LONG BodyPos = NULL;
LONG CAMG = NULL;
LONG *CMAP = NULL;
LONG *Buffer = NULL;
LONG error = ERR_FAILED;
APTR FILBase = GVBase->FileBase; /* Seek() and OpenFile() */
WORD FreeFile = FALSE;
LONG FileSize;
/* Open the file and allocate a read buffer. Note that we check
** if the Picture->Source is an initialised File, because we do
** not want to open the file twice (illegal).
*/
if (((struct Head *)Picture->Source)->ID IS ID_FILE) {
if (CheckInit(Picture->Source) IS TRUE) {
File = Picture->Source;
}
}
if (File IS NULL) {
if ((File = OpenFile(Picture->Source,FL_READ)) IS NULL) {
error = ErrCode(ERR_FILE);
goto exit;
}
else FreeFile = TRUE;
}
Buffer = AllocMemBlock(BUFFERSIZE,MEM_DATA); /* Allocate a 4k buffer */
/*** Check for the initial FORM/ILBM part ***/
Seek(File, 0, POS_START); /* Required in case Picture->Source has been used */
Read(File, Buffer, 12); /* [FORM] [Size] [ILBM] */
if ((Buffer[0] != CODE_FORM) OR (Buffer[2] != CODE_ILBM)) {
DPrintF("!Init:","This file does not start with a FORM/ILBM header.");
error = ERR_DATA;
goto exit;
}
FileSize = Buffer[1];
/*** Read each iff chunk in the file ***/
while ((FileSize > 0) AND (BodyPos IS NULL)) {
if (Read(File,Buffer,8) != 8) { /* [CODE] [Size] */
DPrintF("!Query","I could not read the next chunk.");
goto exit;
}
if (Buffer[1] & 0x00000001) Buffer[1] += 1;
FileSize -= Buffer[1];
if (Buffer[0] IS CODE_CMAP) {
DPrintF("Init:","IFF CMAP header found.");
if (Buffer[1] > BUFFERSIZE) goto exit;
if (CMAP = AllocMemBlock(Buffer[1],MEM_DATA)) {
Read(File, CMAP, Buffer[1]);
}
}
else if (Buffer[0] IS CODE_BMHD) {
DPrintF("Init:","IFF BMHD header found.");
if (Buffer[1] > BUFFERSIZE) goto exit;
if (BMHD = AllocMemBlock(Buffer[1],MEM_DATA)) {
if (Read(File, BMHD, Buffer[1]) != Buffer[1]) {
error = ErrCode(ERR_READ);
goto exit;
}
}
else {
error = ErrCode(ERR_MEMORY);
goto exit;
}
}
else if (Buffer[0] IS CODE_CAMG) {
DPrintF("Init:","IFF CAMG header found.");
if (Buffer[1] > BUFFERSIZE) goto exit;
if (Read(File,Buffer,Buffer[1]) IS Buffer[1]) {
CAMG = Buffer[0];
}
else {
error = ErrCode(ERR_READ);
goto exit;
}
}
else if (Buffer[0] IS CODE_BODY) {
DPrintF("Init:","IFF BODY header found.");
BodyPos = File->BytePos;
}
else {
if (Seek(File, Buffer[1], POS_CURRENT) IS -1) { /* Skip to the next chunk */
DPrintF("!Init:","I could not seek to the correct file position.");
goto exit;
}
}
}
if (BodyPos) {
/* Calling a query on the picture will give us an initialised
** Bitmap that we can play with.
*/
if (Query(Picture) IS ERR_OK) {
if (Picture->Bitmap->Data IS NULL) {
DPrintF("Init:","Allocating Bitmap data space.");
if (!(Picture->Bitmap->Data = AllocMemBlock(Picture->Bitmap->Size, Picture->Bitmap->MemType))) {
DPrintF("!Init:","Could not allocate Bitmap data space.");
return(NULL);
}
Picture->prvData = Picture->Bitmap->Data;
}
Seek(File, BodyPos, POS_START);
error = UnpackPicture(Picture,BMHD,File,CMAP,CAMG);
}
else DPrintF("!Init:","Could not query picture information.");
}
else DPrintF("!Init:","Picture has no BODY chunk.");
exit:
if (Buffer) FreeMemBlock(Buffer);
if (BMHD) FreeMemBlock(BMHD);
if (CMAP) FreeMemBlock(CMAP);
if (FreeFile IS TRUE) Free(File);
return(error);
}
/************************************************************************************
** Action: Load()
** Object: Picture
**
** Loads in an object file that is known to be of the Picture class. This action
** will get the palette of the Picture if there is one, and store the data in
** standard memory.
**
** We use the File->Source rather than just the File, because we must assume
** that the File object will be freed by Load() and only the source will continue
** to be valid.
*/
LIBFUNC struct Picture * PIC_Load(mreg(__a0) struct File *File)
{
struct Picture *Picture;
Picture = InitTags(NULL,
TAGS_PICTURE, NULL,
PCA_Source, File->Source,
TAGEND);
return(Picture);
}
/************************************************************************************
** Action: Query()
** Object: Picture
**
** Gets picture information - width, height, amount of colors, planes etc. It does
** not grab the data of the picture.
*/
LIBFUNC LONG PIC_Query(mreg(__a0) struct Picture *Picture)
{
struct BMHD *BMHD = NULL;
struct File *File = NULL;
struct Bitmap *Bitmap;
LONG error = ERR_FAILED; /* The default code is for failure */
LONG CAMG = NULL;
LONG *CMAP = NULL;
LONG CMAPSize = NULL; /* Size of the CMAP array */
LONG *Buffer = NULL;
WORD FreeFile = FALSE;
APTR BLTBase = GVBase->BlitterBase; /* GetBmpType() */
APTR FILBase = GVBase->FileBase; /* Seek() and OpenFile() */
BYTE *SrcPalette;
BYTE *DestPalette;
LONG i;
APTR Temp;
LONG FileSize;
DPrintF("~Query()","Picture: $%x", Picture);
/*** Validation procedures ***/
if ((Bitmap = Picture->Bitmap) IS NULL) {
DPrintF("!Query;","No Picture->Bitmap present.");
goto exit;
}
/* Open the file and allocate a read buffer. Note that we check
** if the Picture->Source is an initialised File, because we do
** not want to open the file twice (illegal).
*/
if (((struct Head *)Picture->Source)->ID IS ID_FILE) {
if (CheckInit(Picture->Source) IS TRUE) {
File = Picture->Source;
}
}
if (File IS NULL) {
if ((File = OpenFile(Picture->Source,FL_READ)) IS NULL) {
error = ErrCode(ERR_FILE);
goto exit;
}
else FreeFile = TRUE;
}
Buffer = AllocMemBlock(BUFFERSIZE,MEM_DATA); /* Allocate a 4k buffer */
/*** Check for the initial FORM/ILBM part ***/
Seek(File, 0, POS_START); /* Required in case Picture->Source has been used */
Read(File, Buffer, 12); /* [FORM] [Size] [ILBM] */
if ((Buffer[0] != CODE_FORM) OR (Buffer[2] != CODE_ILBM)) {
DPrintF("!Query:","This file does not start with a FORM/ILBM header.");
error = ERR_DATA;
goto exit;
}
FileSize = GetFSize(File);
/*** Read each iff chunk in the file ***/
while (File->BytePos < FileSize) {
if (Read(File,Buffer,8) != 8) { /* [CODE] [Size] */
DPrintF("!Query:","I could not read the next chunk.");
break;
}
if (Buffer[1] & 0x00000001) Buffer[1] += 1;
if (Buffer[0] IS CODE_CMAP) {
DPrintF("Query:","IFF CMAP header found.");
if (Buffer[1] > BUFFERSIZE) goto exit;
CMAPSize = Buffer[1]/3;
if (CMAP = AllocMemBlock(Buffer[1],MEM_DATA)) {
Read(File, CMAP, Buffer[1]);
}
}
else if (Buffer[0] IS CODE_BMHD) {
DPrintF("Query:","IFF BMHD header found.");
if (Buffer[1] > BUFFERSIZE) goto exit;
if (BMHD = AllocMemBlock(Buffer[1],MEM_DATA)) {
if (Read(File, BMHD, Buffer[1]) != Buffer[1]) {
error = ErrCode(ERR_READ);
goto exit;
}
}
else {
error = ErrCode(ERR_MEMORY);
goto exit;
}
}
else if (Buffer[0] IS CODE_CAMG) {
DPrintF("Query:","IFF CAMG header found.");
if (Buffer[1] > BUFFERSIZE) goto exit;
if (Read(File,Buffer,Buffer[1]) IS Buffer[1]) {
CAMG = Buffer[0];
}
else {
error = ErrCode(ERR_READ);
goto exit;
}
}
else {
DPrintF("Query:","Unused chunk, skipping %ld bytes.",Buffer[1]);
if (Seek(File, Buffer[1], POS_CURRENT) IS -1) { /* Skip to the next chunk */
DPrintF("!Query:","I could not seek to the correct file position.");
goto exit;
}
}
}
if (BMHD) {
if (Bitmap->AmtColours IS NULL) Bitmap->AmtColours = CMAPSize;
if (Bitmap->Height IS NULL) Bitmap->Height = BMHD->Height;
if (Bitmap->Planes IS NULL) Bitmap->Planes = BMHD->Depth;
if (Bitmap->Type IS NULL) Bitmap->Type = GetBmpType(); /* User preference */
if (Picture->ScrWidth IS NULL) Picture->ScrWidth = BMHD->ScrWidth;
if (Picture->ScrHeight IS NULL) Picture->ScrHeight = BMHD->ScrHeight;
if (Bitmap->Width IS NULL) {
Bitmap->Width = BMHD->Width;
Bitmap->ByteWidth = NULL; /* Let the Init(Bitmap) calculate it */
}
}
if (CAMG) {
/* Note that if the programmer has preset a non-planar mode,
** then we cannot set HAM or EHB bits (the picture will be
** converted so special graphic flags do not apply).
*/
if ((Bitmap->Type IS ILBM) OR (Bitmap->Type IS PLANAR)) {
if ((Bitmap->Planes IS 6) OR (Bitmap->Planes IS 8)) {
if (CAMG & OSV_HAM) Picture->Bitmap->Flags |= BMF_HAM;
if (CAMG & OSV_EHB) Picture->Bitmap->Flags |= BMF_EXTRAHB;
}
}
if (CAMG & OSV_LACED) Picture->ScrMode |= SM_LACED;
if (CAMG & OSV_HIRES) {
Picture->ScrMode |= SM_HIRES;
}
else Picture->ScrMode |= SM_LORES;
}
/*** Generate Palette ***/
if ((Bitmap->Palette IS NULL) AND (Bitmap->AmtColours <= 256) AND (CMAP)) {
if (Bitmap->Palette = AllocMemBlock((Bitmap->AmtColours * 4)+8,MEM_DATA)) {
Picture->prvPalette = Bitmap->Palette;
Bitmap->Palette[0] = PALETTE_ARRAY;
Bitmap->Palette[1] = Bitmap->AmtColours;
SrcPalette = (BYTE *)CMAP;
DestPalette = ((BYTE *)Bitmap->Palette)+8;
for (i=0; i < Bitmap->AmtColours; i++) {
DestPalette[1] = SrcPalette[0];
DestPalette[2] = SrcPalette[1];
DestPalette[3] = SrcPalette[2];
DestPalette += 4;
SrcPalette += 3;
}
}
else {
error = ErrCode(ERR_MEMORY);
goto exit;
}
}
/*** Initialise (or re-initialise) the Picture->Bitmap ***/
Temp = Bitmap->Data;
Bitmap->Data = (APTR)-1; /* Fake the data pointer to prevent an allocation */
if (Init(Bitmap, NULL) IS NULL) {
DPrintF("!Query:","Could not initialise bitmap.");
goto exit;
}
Bitmap->Data = Temp;
error = ERR_OK;
exit:
if (Buffer) FreeMemBlock(Buffer);
if (BMHD) FreeMemBlock(BMHD);
if (CMAP) FreeMemBlock(CMAP);
if (FreeFile IS TRUE) Free(File);
StepBack();
return(error);
}
/************************************************************************************
** Actions: File support.
** Object: Picture
** Short: These routines allow you to read/write to a Picture's Bitmap.
*/
LIBFUNC LONG PIC_Read(mreg(__a0) struct Picture *Picture, mreg(__a1) BYTE *Buffer, mreg(__d0) LONG Length) {
return(Read(Picture->Bitmap,Buffer,Length));
}
LIBFUNC LONG PIC_Seek(mreg(__a0) struct Picture *Picture, mreg(__d0) LONG Offset, mreg(__d1) WORD Position) {
return(Seek(Picture->Bitmap,Offset,Position));
}
LIBFUNC LONG PIC_Write(mreg(__a0) struct Picture *Picture, mreg(__a1) BYTE *Buffer, mreg(__d0) LONG Length) {
return(Write(Picture->Bitmap,Buffer,Length));
}